<template>
  <Page ref="page" :title="navTitle">
    <template #navBarCustom>
      <div class="flex items-center navBox">
        <div class="back" @click="back">
          <img class="icon" src="static/icons/back.png" mode="" />
          <span style="color: #fff">{{ navTitle }}</span>
        </div>
        <div class="nav-bar-btns flex" style="margin-left: auto">
          <div class="item flex items-center">
            <img class="icon mt-2px mr-4px" src="static/icons/clock.png" mode="" />
            <span class="name text-white">{{ $utils.formatSeconds(cumulativeTime.value) }}</span>
          </div>
        </div>
      </div>
    </template>
    <template #content>
      <div class="w-full h-full p-20px box-border">
        <!-- 客观题 -->
        <Objective
          ref="objective"
          :questions="questions"
          :question-index="questionIndex"
          :has-more-question="hasMoreQuestion"
          @submit="submit"
          @prev="prevQuestion"
          @next="nextQuestion"
        />
        <!-- 主观题 -->
        <Subjective
          ref="subjective"
          :questions="questions"
          :question-index="questionIndex"
          :has-more-question="hasMoreQuestion"
          @submit="submit"
          @prev="prevQuestion"
          @next="nextQuestion"
        />

        <!-- 退出练习弹窗 -->
        <div class="quit-practice-dialog-wrap" v-show="isShowQuitPracticeDialog">
          <div class="quit-practice-dialog bg-white px-24px py-30px relative flex flex-col">
            <div class="header relative w-full flex justify-center items-center text-white">
              <img
                class="close absolute"
                src="static/icons/close.png"
                mode=""
                @click="isShowQuitPracticeDialog = false"
              />
              <div class="title font-medium text-262A30">提示</div>
            </div>
            <div class="main text-A3A3A3 py-30px flex-center flex-1">
              已练习{{ practiceCount }}道题目，确认退出本次练习？
            </div>
            <div class="footer flex justify-center">
              <CustomButton class="block" style="width: 2rem" @click="quitPractice"
                >确认</CustomButton
              >
            </div>
          </div>
        </div>
         <!-- 退出练习弹窗 -->
    <div class="quit-practice-dialog-wrap" v-show="isShowSelectDialog">
      <div class="quit-practice-dialog bg-white px-24px py-30px relative flex flex-col">
        <div class="header relative w-full flex justify-center items-center text-white">
          <img
            class="close absolute"
            src="static/icons/close.png"
            mode=""
            @click="isShowSelectDialog = false"
          />
          <div class="title font-medium text-262A30">提示</div>
        </div>
        <div class="main text-A3A3A3 py-30px flex-center flex-1"> 请先选择是否做对？ </div>
        <div class="footer flex justify-center">
          <CustomButton class="block" style="width: 2rem" @click="isShowSelectDialog = false"
            >好的</CustomButton
          >
        </div>
      </div>
    </div>
      </div>
    </template>
  </Page>
</template>

<script>
// import Page from '@/components/page'
import Page from '@/components/page/newPage'
import Objective from './components/objective/index'
import Subjective from './components/subjective/index'
import CustomButton from '@/components/button'
import { mapState } from 'vuex'
import {
  getNextQuestion,
  checkAnswer,
  updateAnswerApi,
  recommendCheckAnswer,
  quitPracticeApi
} from '@/api/exercise'
import { getSimilarRecommend, exitRecommendUseRecord } from '@/api/wq-book'
import { checkStudyClockinApi, updateTodayStatusApi } from '@/api/daily-attendance'

export default {
  components: {
    Page,
    Objective,
    Subjective,
    CustomButton
  },
  beforeRouteLeave(to, from, next) {
    // 主观题如果没选择是否做对，不能直接退出
    if (!this.currentQuestion.answerScoreable) {
      const { isShowAnalysis, status } = this.$refs.subjective.$data

      if (isShowAnalysis && status === 0) {
        this.isShowSelectDialog=true
        window.history.pushState(null, null, '/#/pages/exercise/practice/xkw/index')
        return
      }
    }

    if (this.canBack) {
      next()
    } else {
      // 显示退出练习弹窗
      this.isShowQuitPracticeDialog = true
      window.history.pushState(null, null, '/#/pages/exercise/practice/xkw/index')
    }
  },
  props: {},
  data() {
    return {
      studyClockinDetailList: [], // 所有未结束的每日打卡任务详情列表
      studyClockinDetailIds: [], // 所有未结束的每日打卡任务详情id列表
      isShowQuitPracticeDialog: false, // 是否显示退出练习弹窗
      isShowSelectDialog:false,
      canBack: false,
      // 累计时间
      cumulativeTime: {
        vm: this._self,
        caches: {},
        timeout: null,
        value: 0, // 单位：秒
        // 累加
        run: function () {
          this.timeout = setTimeout(() => {
            this.value++
            this.vm.$refs.page && this.vm.$refs.page.$forceUpdate()
            this.run()
          }, 1000)
        },
        reset: function () {
          clearTimeout(this.timeout)
          this.value = 0
        },
        stop: function () {
          // 清除定时器
          clearTimeout(this.timeout)

          // 缓存
          const { questionId } = this.vm.currentQuestion
          this.caches[questionId] = this.value
        }
      },
      rankScore: 1, // 学生分数
      correctTimes: 0, // 连续作对次数
      hasMoreQuestion: true, // 是否已做完所有题目
      practiceCount: 0 // 做题数量累计
    }
  },
  computed: {
    ...mapState(['exerciseCenter']),
    questions() {
      const { questions } = this.exerciseCenter.currentPractice

      return questions
    },
    questionIndex() {
      const { questionIndex } = this.exerciseCenter.currentPractice

      return questionIndex
    },
    currentQuestion() {
      return this.questions[this.questionIndex]
    },
    navTitle() {
      const {
        record: { practiceName }
      } = this.exerciseCenter.currentPractice

      return practiceName
    }
  },
  watch: {
    questionIndex() {
      this.cumulativeTime.reset()

      const currentQuestion = this.questions[this.questionIndex]
      if (!currentQuestion.temp) {
        this.cumulativeTime.run()
      } else {
        const cumulativeTimeValue = this.cumulativeTime.caches[currentQuestion.questionId]
        if (cumulativeTimeValue) {
          this.cumulativeTime.value = cumulativeTimeValue
        }
      }
    }
  },
  created() {
    this.init()
  },
  mounted() {
    this.cumulativeTime.run()
  },
  methods: {
    back() {
      if (this.onBack) {
        this.onBack()
      } else {
        this.$router.go(-1)
      }
    },
    init() {
      // 查询是否存在打卡任务
      const { record } = this.exerciseCenter.currentPractice
      const isRecommend = !!record.questionId // true => 举一反三 false => 习题中心
      if (isRecommend) {
        const { subject: subjectId, kpointIds } = record
        checkStudyClockinApi({
          subjectId,
          kpointIds: kpointIds.join(','),
          type: 1
        }).then(({ data }) => {
          if (Array.isArray(data)) {
            this.studyClockinDetailList = data
            this.studyClockinDetailIds = data.map((item) => item.id)
          }
        })
      } else {
        const { courseId: subjectId, kpointIds } = record
        checkStudyClockinApi({
          subjectId,
          kpointIds: kpointIds.join(','),
          type: 2
        }).then(({ data }) => {
          if (Array.isArray(data)) {
            this.studyClockinDetailList = data
            this.studyClockinDetailIds = data.map((item) => item.id)
          }
        })
      }
      // 记录分数
      const {
        query: { rankScore }
      } = this.$route

      const score = parseFloat(rankScore)

      if (!(score >= 0)) return

      this.rankScore = score
    },
    getStudentLevel(score) {
      if (!score) return 1

      if (score >= 0 && score <= 10) {
        return 1
      }

      if (score > 10 && score <= 20) {
        return 2
      }

      if (score > 20 && score <= 50) {
        return 3
      }

      if (score > 50 && score <= 70) {
        return 4
      }

      if (score > 70) {
        return 5
      }
    },
    getQuestionScore() {
      const {
        record: { difficultyLevel }
      } = this.exerciseCenter.currentPractice

      const compute = (baseMinusValue, baseAddValue) => {
        if (this.correctTimes === 0) {
          return baseMinusValue
        }

        if (this.correctTimes < 3) {
          return baseAddValue
        }

        if (this.correctTimes === 3) {
          return baseAddValue + 3
        }

        if (this.correctTimes >= 4 && this.correctTimes < 7) {
          return baseAddValue + 2
        }

        if (this.correctTimes >= 7 && this.correctTimes < 11) {
          return baseAddValue + 3
        }

        if (this.correctTimes >= 11) {
          return baseAddValue + 4
        }
      }

      switch (this.getStudentLevel(this.rankScore)) {
        case 1:
          // 青铜
          switch (difficultyLevel) {
            case '17':
              // 容易
              return compute(-0.5, 1)
            case '18':
              // 较易
              return compute(-1.5, 2)
            case '19':
              // 一般
              return compute(-2.5, 3)
            case '20':
              // 较难
              return compute(-3.5, 4)
            case '21':
              // 困难
              return compute(-4.5, 5)
            default:
              return 0
          }
        case 2:
          // 白银
          switch (difficultyLevel) {
            case '17':
              // 容易
              return 0
            case '18':
              // 较易
              return compute(-1.5, 2)
            case '19':
              // 一般
              return compute(-2.5, 3)
            case '20':
              // 较难
              return compute(-3.5, 4)
            case '21':
              // 困难
              return compute(-4.5, 5)
            default:
              return 0
          }
        case 3:
          // 黄金
          switch (difficultyLevel) {
            case '17':
              // 容易
              return 0
            case '18':
              // 较易
              return 0
            case '19':
              // 一般
              return compute(-2.5, 3)
            case '20':
              // 较难
              return compute(-3.5, 4)
            case '21':
              // 困难
              return compute(-4.5, 5)
            default:
              return 0
          }
        case 4:
          // 钻石
          switch (difficultyLevel) {
            case '17':
              // 容易
              return 0
            case '18':
              // 较易
              return 0
            case '19':
              // 一般
              return 0
            case '20':
              // 较难
              return compute(-3.5, 4)
            case '21':
              // 困难
              return compute(-4.5, 5)
            default:
              return 0
          }
        case 5:
          // 王者
          switch (difficultyLevel) {
            case '17':
              // 容易
              return 0
            case '18':
              // 较易
              return 0
            case '19':
              // 一般
              return 0
            case '20':
              // 较难
              return 0
            case '21':
              // 困难
              return compute(-4.5, 5)
            default:
              return 0
          }
        default:
          return 0
      }
    },
    checkAnswer(data, isRecommend = false) {
      return new Promise(async (resolve) => {
        let fn = undefined
        if (!isRecommend) {
          // 习题练习
          fn = checkAnswer

          // 统计连续作对次数
          const { correct } = data
          if (correct == 1) {
            this.correctTimes = 0
          } else {
            this.correctTimes++
          }

          // 计算分数
          const { rankScore } = this
          const questionScore = this.getQuestionScore()
          this.rankScore = rankScore + questionScore
          if (this.rankScore < 0) this.rankScore = 0
          data['questionScore'] = questionScore
        } else {
          // 举一反三
          fn = recommendCheckAnswer
        }

        const { code, data: practiceStudentQuestionIds, msg } = await fn(data)

        if (code === 0) {
          if (Array.isArray(practiceStudentQuestionIds) && practiceStudentQuestionIds.length > 0) {
            const practiceStudentQuestionId =
              practiceStudentQuestionIds[practiceStudentQuestionIds.length - 1]
            const { currentQuestion } = this
            currentQuestion['practiceStudentQuestionId'] = practiceStudentQuestionId
          }
        } else {
          this.$message.info(msg)
        }

        resolve('')
      })
    },
    // 提交答案
    async submit(data) {
      // 加载动画
      const loading = this.$loading({
        lock: true,
        text: '正在提交...',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.5)'
      })
      // 一分钟内加载不成功关闭loading弹窗
      const timer = setTimeout(() => {
        loading.close()
      }, 60000)

      const { practiceStudentQuestionId, temp } = this.currentQuestion
      const {
        currentPractice: {
          record: { id: practiceId, userKpointDataId, questionId }
        }
      } = this.exerciseCenter

      // 存在practiceStudentQuestionId => 未提交，提交答案
      // 不存在practiceStudentQuestionId => 已提交，更新答案
      if (!practiceStudentQuestionId) {
        // 判断是否举一反三
        const isRecommend = !!questionId
        // 练习记录id
        data['practiceId'] = practiceId
        // 用户知识点数据Id
        data['userKpointDataId'] = userKpointDataId
        // 练习时长 -> 时间戳
        data['practiceDuration'] = this.cumulativeTime.value * 1000
        // 停止计时
        this.cumulativeTime.stop()

        await this.checkAnswer(data, isRecommend)
        this.practiceCount++

        // 如果存在打卡任务
        if (this.studyClockinDetailIds.length > 0) {
          const { answerScoreable, studentAnswerUrl } = data

          // 客观题直接更新打卡记录，如果主观题没有上传答案图片，不更新打卡记录
          if (answerScoreable || (!answerScoreable && studentAnswerUrl)) {
            this.studyClockinDetailIds.forEach((id) => {
              updateTodayStatusApi({
                id,
                studentQuestionDuration: data.practiceDuration / 1000,
                studentQuestionNum: 1,
                studentQoNum: answerScoreable ? 1 : 0, // 客观题数量
                studentQsNum: answerScoreable ? 0 : 1, // 主观题数量
                type: isRecommend ? 1 : 2 // 1 => 举一反三 2 => 习题中心
              })
            })
          }
        }
      } else {
        const { correct, errors } = data

        const { code } = await updateAnswerApi({
          practiceStudentQuestionId,
          practiceId,
          userKpointDataId,
          ...data
        })

        if (temp && code === 0) {
          temp.isAddWqBook = errors === 0 ? true : false

          if (temp.status) {
            temp.status = correct === 0 ? 1 : 2
          }
        }
      }

      // 关闭加载动画
      clearTimeout(timer)
      loading.close()
    },
    // 上一题
    prevQuestion() {
      const { currentPractice } = this.exerciseCenter

      currentPractice.questionIndex--
    },
    // 下一题 overwrite => 是否覆盖当前问题
    async nextQuestion({ overwrite = false } = {}) {
      const { currentPractice } = this.exerciseCenter
      // 如果有缓存，直接进入下一题
      if (this.questionIndex < this.questions.length - 1) {
        currentPractice.questionIndex++
      } else {
        // 加载动画
        const loading = this.$loading({
          lock: true,
          text: '加载中...',
          spinner: 'el-icon-loading',
          background: 'rgba(0, 0, 0, 0.5)'
        })
        // 一分钟内加载不成功关闭loading弹窗
        const timer = setTimeout(() => {
          loading.close()
        }, 60000)

        const {
          currentPractice: {
            record: { subject, questionId, courseId, kpointId, difficultyLevel }
          }
        } = this.exerciseCenter
        const isRecommend = !!questionId

        const { data: nextQuestionItem, msg } = !isRecommend
          ? await getNextQuestion({
              courseId,
              kpointId,
              difficultyLevel,
              detailIds: this.studyClockinDetailIds
            })
          : await getSimilarRecommend({
              subjectId: subject,
              questionId,
              detailIds: this.studyClockinDetailIds
            })

        if (!nextQuestionItem) {
          this.$message.info(msg)
          this.hasMoreQuestion = false
          // 关闭加载动画
          clearTimeout(timer)
          loading.close()
          return
        } else {
          this.hasMoreQuestion = true
        }

        if (isRecommend) {
          const { practiceId } = nextQuestionItem
          currentPractice.record.id = practiceId
        }

        if (overwrite) {
          // 跳过当前问题，进入下一题
          currentPractice.questions.splice(currentPractice.questionIndex, 1, nextQuestionItem)
          this.cumulativeTime.reset()
          this.cumulativeTime.run()
        } else {
          currentPractice.questions.push(nextQuestionItem)
          currentPractice.questionIndex++
        }

        // 关闭加载动画
        clearTimeout(timer)
        loading.close()
      }
    },
    async quitPractice() {
      const {
        currentPractice: {
          record: { id, recommendUseRecordId = null }
        }
      } = this.exerciseCenter

      // 加载动画
      const loading = this.$loading({
        lock: true,
        text: '保存中...',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.5)'
      })
      // 一分钟内加载不成功关闭loading弹窗
      const timer = setTimeout(() => {
        loading.close()
      }, 60000)

      if (recommendUseRecordId) {
        await exitRecommendUseRecord({
          id: recommendUseRecordId
        })
      }

      await quitPracticeApi({
        id
      })

      // 关闭加载动画
      clearTimeout(timer)
      loading.close()

      this.canBack = true
      this.$router.back()
    }
  }
}
</script>

<style lang="scss" scoped>
.navBox {
  padding: 0 20px;
  box-sizing: border-box;
}
.back {
  height: 100%;
  display: flex;
  align-items: center;
  font-size: 28px;

  .icon {
    width: 17.14px;
    height: 30px;
    margin-right: 11px;
  }
}
.nav-bar-btns {
  .item {
    height: 30px;
    .icon {
      width: 34px;
      height: 34px;
    }

    .name {
      font-size: 26px;
    }
  }
}

.quit-practice-dialog-wrap {
  width: 100vw;
  height: 100vh;
  background: rgba($color: #000000, $alpha: 0.5);
  position: absolute;
  left: 0;
  top: 0;
  z-index: 1999;

  .quit-practice-dialog {
    width: 348px;
    min-height: 158px;
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    border-radius: 16px;
    border: 1px solid #707070;

    .header {
      .close {
        width: 16px;
        height: 16px;
        top: -12px;
        right: -8px;
      }

      .title {
        font-size: 26px;
        line-height: 30px;
      }
    }

    .main {
      font-size: 26px;
      line-height: 28px;
    }

    .footer {
    }
  }
}

/deep/ .stem {
  font-size: 20px;
  line-height: 28px;

  .question-type {
    font-size: 18px;
    background-color: rgba(81, 195, 255, 0.1);
    border-radius: 4px;
  }

  .paragraph {
    &:not(:first-child) {
      margin-top: 10px;
    }
  }
}

/deep/ .qml-answer {
  font-size: 26px;
}

/deep/ .qml-explanation {
  font-size: 26px;

  .qml-seg {
    color: #333;
    margin-bottom: 12px;

    &:last-child {
      margin-bottom: 0;
    }
  }

  .paragraph {
    color: #333;
    margin-top: 12px;
  }
}
</style>
